package com.ctg.itrdc.imageconsole.control.ssh.db;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.UUID;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ctg.itrdc.imageconsole.control.ssh.model.Auth;
import com.ctg.itrdc.imageconsole.control.ssh.model.User;
import com.ctg.itrdc.imageconsole.control.ssh.utils.DBUtils;
import com.ctg.itrdc.imageconsole.control.ssh.utils.ExternalAuthUtil;


/**
 * DAO to login administrative user
 */
public class AuthDB {

    private static Logger log = LoggerFactory.getLogger(AuthDB.class);

    private AuthDB() {
    }

    /**
     * auth user and return auth token if valid auth
     *
     * @param auth username and password object
     * @return auth token if success
     */
    public static String login(Auth auth) {
        //check ldap first
        String authToken = ExternalAuthUtil.login(auth);
        
        if (StringUtils.isEmpty(authToken)) {
            Connection con = null;
            try {
                con = DBUtils.getConn();
                PreparedStatement stmt = con.prepareStatement("select * from user where status='001' and username=? and password=?");
                stmt.setString(1, auth.getUsername());
                stmt.setString(2, auth.getPassword());
                ResultSet rs = stmt.executeQuery();
                if (rs.next()) {
                    auth.setId(rs.getLong("id"));
                    authToken = UUID.randomUUID().toString();
                    auth.setAuthToken(authToken);
                    updateLogin(con, auth);

                }
                DBUtils.closeRs(rs);
                DBUtils.closeStmt(stmt);
            } catch (Exception e) {
                log.error(e.toString(), e);
            }

            DBUtils.closeConn(con);
        }

        return authToken;
    }

    /**
     * updates the admin table based on auth id
     *
     * @param con  DB connection
     * @param auth username and password object
     */
    public static void updateLogin(Connection con, Auth auth) {
        try {
            PreparedStatement stmt = con.prepareStatement("update user set username=?, auth_token=?, password=? where id=?");
            stmt.setString(1, auth.getUsername());
            stmt.setString(2, auth.getAuthToken());
            if (StringUtils.isNotEmpty(auth.getPassword())) {
                stmt.setString(3, auth.getPassword());
            } else {
                stmt.setString(3, null);
            }
            stmt.setLong(4, auth.getId());
            stmt.execute();

            DBUtils.closeStmt(stmt);

        } catch (Exception e) {
            log.error(e.toString(), e);
        }
    }

    /**
     * updates password for admin using auth token
     */
    public static boolean updatePassword(Auth auth) {
        boolean success = false;

        Connection con = null;
        try {
            con = DBUtils.getConn();
            PreparedStatement stmt = con.prepareStatement("select * from user where auth_token like ? and password like ?");
            stmt.setString(1, auth.getAuthToken());
            stmt.setString(2, auth.getPrevPassword());
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {

                stmt = con.prepareStatement("update user set password=? where auth_token like ?");
                stmt.setString(1, auth.getPassword());
                stmt.setString(2, auth.getAuthToken());
                stmt.execute();
                success = true;
            }
            DBUtils.closeRs(rs);
            DBUtils.closeStmt(stmt);

        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        DBUtils.closeConn(con);
        return success;
    }

    /**
     * returns user id based on auth token
     *
     * @param authToken auth token
     * @param con       DB connection
     * @return user
     */
    public static User getUserByAuthToken(Connection con, String authToken) {
        User user = null;
        try {
            PreparedStatement stmt = con.prepareStatement("select * from user where status='001' and auth_token like ?");
            stmt.setString(1, authToken);
            ResultSet rs = stmt.executeQuery();
            if (rs.next()) {
                Long userId = rs.getLong("id");
                user=UserDB.getUser(con, userId);
            }
            DBUtils.closeRs(rs);
            DBUtils.closeStmt(stmt);

        } catch (Exception e) {
            log.error(e.toString(), e);
        }


        return user;

    }

    /**
     * returns user based on auth token
     *
     * @param authToken auth token
     * @return user
     */
    public static User getUserByAuthToken(String authToken) {

        User user = null;
        Connection con = null;
        try {
            con = DBUtils.getConn();
            user = getUserByAuthToken(con, authToken);
        } catch (Exception e) {
            log.error(e.toString(), e);
        }
        DBUtils.closeConn(con);

        return user;

    }
    /**
     * returns user base on username
     *
     * @param con DB connection
     * @param uid username id
     * @return user object
     */
    public static User getUserByUID(Connection con, String uid) {

        User user = null;
        try {
            PreparedStatement stmt = con.prepareStatement("select * from  user where lower(username) like lower(?) and status='001'");
            stmt.setString(1, uid);
            ResultSet rs = stmt.executeQuery();

            while (rs.next()) {
                user = new User();
                user.setId(rs.getLong("id"));
                user.setUsername(rs.getString("username"));
            }
            DBUtils.closeRs(rs);
            DBUtils.closeStmt(stmt);

        } catch (Exception e) {
            log.error(e.toString(), e);
        }

        return user;
    }
}
